Skip to content

Upload playground standalone emitters#10225

Closed
timotheeguerin wants to merge 110 commits intomicrosoft:mainfrom
timotheeguerin:standalone-emitter-upload-playground
Closed

Upload playground standalone emitters#10225
timotheeguerin wants to merge 110 commits intomicrosoft:mainfrom
timotheeguerin:standalone-emitter-upload-playground

Conversation

@timotheeguerin
Copy link
Copy Markdown
Member

No description provided.

@microsoft-github-policy-service microsoft-github-policy-service bot added meta:website TypeSpec.io updates emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp emitter:client:python Issue for the Python client emitter: @typespec/http-client-python eng labels Mar 31, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

No changes needing a change description found.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 31, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@10225

commit: 2681f2d

@azure-sdk
Copy link
Copy Markdown
Collaborator

azure-sdk commented Mar 31, 2026

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

timotheeguerin and others added 3 commits April 1, 2026 11:21
Pipeline PackagePath values start with '/' (e.g. '/packages/http-client-csharp')
which causes path.resolve() to treat it as an absolute path, ignoring repoRoot.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft
Copy link
Copy Markdown
Contributor

The upload step fails because the emitter dist/ doesn't exist when createTypeSpecBundle runs. The pipeline installs and builds bundle-uploader but not the emitter itself.

The fix: add emitter build steps before the bundle upload. For http-client-csharp, add these steps before the pnpm install for bundle-uploader:

    - script: npm ci
      displayName: Install emitter dependencies
      workingDirectory: $(Build.SourcesDirectory)/${{ parameters.PackagePath }}
    - script: npm run build:emitter
      displayName: Build emitter
      workingDirectory: $(Build.SourcesDirectory)/${{ parameters.PackagePath }}

The emitter packages (http-client-csharp, http-client-python) are outside the pnpm workspace, so pnpm build doesn't cover them — they need their own npm ci + build step.

The emitter packages (http-client-csharp, http-client-python) are
outside the pnpm workspace, so pnpm build doesn't cover them.
Add npm ci + npm run build:emitter steps before bundling.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft
Copy link
Copy Markdown
Contributor

I pushed the fix to JoshLove-msft/typespec branch fix/emitter-upload-build (based on your branch).

The change adds npm ci + npm run build:emitter steps before the bundle upload. The emitter packages are outside the pnpm workspace so they need their own build step.

Diff: JoshLove-msft@2814ed0fc

JoshLove-msft and others added 4 commits April 2, 2026 14:20
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Browser-compatible emitter (dynamic imports), playground-server-url
option, .NET playground server, and serialization optimization.

From PR microsoft#10189.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The publish stage doesn't have the .NET SDK installed. Only the
TypeScript emitter build is needed for the playground bundle.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Python uses 'build' (default), C# uses 'build:emitter' to skip
the .NET generator build which requires the .NET SDK.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft
Copy link
Copy Markdown
Contributor

The published emitter bundle (1.0.0) doesn't have the browser-compatible changes from PR #10189. It still has static import { fileURLToPath } from "url" which the bundler polyfills with a shim that references Deno.

PR #10189 makes these imports dynamic so the emitter module loads in the browser. That PR needs to merge before this upload pipeline produces a working bundle.

The error path: fileURLToPath is called because the emitter goes directly to runLocalGenerator (the Node.js code path) — the browser detection and generateViaPlaygroundServer code path doesn't exist in the published version.

JoshLove-msft and others added 8 commits April 3, 2026 09:54
The url module polyfill references Deno which crashes in browser.
Set fs, url, and child_process to empty shims since emitter code
that uses them is behind runtime guards and never executes in the
browser. Keep path polyfilled since it's commonly used in
browser-safe code.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the package.json browser field to swap the Node.js emit-generate
module with a browser stub that calls the playground server via fetch.
This follows the same pattern as alloy-framework/alloy#376.

- emit-generate.ts: Node.js implementation (uses fs, child_process, url)
- emit-generate.browser.ts: browser stub (uses fetch to call server)
- emitter.ts: clean of all Node.js imports, delegates to generate()
- package.json: browser field maps the module swap

The bundler respects the browser field and swaps the import at build
time, so no Node.js polyfills are needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update  tests to verify generate() is called with correct
options instead of execCSharpGenerator (which moved to emit-generate.ts).
Re-export _validateDotNetSdk from emitter.ts for test compatibility.
Mock emit-generate.js with importOriginal to preserve _validateDotNetSdk.

All 195 emitter tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The code model was being serialized with plain JSON.stringify, losing
the reference tracking (/) and usage flag transformations that
the .NET generator requires. Use serializeCodeModel() from
code-model-writer which applies buildJson() and transformJSONProperties.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The browser bundle can't resolve this export since
emit-generate.browser.ts doesn't export it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move _validateDotNetSdk tests to validate-dotnet-sdk.test.ts to avoid
vitest module mock conflicts between  tests (which mock
emit-generate.js) and _validateDotNetSdk tests (which need the real
emit-generate.js).

All 195 emitter tests pass across 24 test files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
JoshLove-msft and others added 29 commits April 11, 2026 13:02
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Load generator assembly and invoke entry point directly via reflection
instead of spawning a dotnet subprocess. The SIGSEGV appears to be
triggered by process forking in the App Service container sandbox.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
App Service sandbox may enforce W^X on JIT pages, causing SIGSEGV when
Roslyn's compiled code is executed. DOTNET_EnableWriteXorExecute=0
disables this protection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…overy)

The generator uses MEF DirectoryCatalog(AppContext.BaseDirectory) to
find ScmCodeModelGenerator. In-process, AppContext.BaseDirectory points
to the server dir, not the generator dir. Reverting to subprocess but
with W^X and mmap fixes in the Dockerfile.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Roslyn's Simplifier.ReduceAsync and GetCompilationAsync crash with
SIGSEGV in App Service containers. The new flag writes raw generated
code directly without Roslyn post-processing (simplification,
formatting, unused type removal). Code is valid C# but uses
fully-qualified type names.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Linux App Service sandbox causes SIGSEGV during Roslyn compilation.
Windows containers run in Hyper-V with no such restriction.

- Dockerfile: nanoserver-ltsc2022 base
- Pipeline: --platform windows, --hyper-v plan
- Reverted all generator skip-post-processing changes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add [diag] log lines between every Roslyn operation to pinpoint exactly
which call triggers the SIGSEGV.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Run files one at a time instead of parallel Task.WhenAll to identify
exactly which file/type triggers the SIGSEGV.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Emitter.Info writes to stdout JSON-RPC which may buffer. Switch to
Console.Error.WriteLine + Flush to ensure logs appear before crash.
Also added logging inside PostProcessAsync and GetGeneratedFilesAsync.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Split logging to identify if crash is in ProcessTypeForBackCompatibility,
writer.Write(), or AddGeneratedFile for the TypeFormatters type.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rsion

The Widgets rest client type crashes during writer.Write() which
recursively writes deeply nested expression trees. This may be a
stack overflow in the App Service container's restricted stack.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ArrayPool.Shared uses mmap-backed allocations on Linux for large
segments. In App Service sandbox, this may cause SIGSEGV. Private pool
uses simple managed arrays instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
If it's a stack overflow, the 64MB thread will survive. If the thread
still crashes, codeFile will be null and we'll log it. Also logs type
info (method count, property count, concrete type name).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pre-compile generator assemblies with PublishReadyToRun to reduce
runtime JIT compilation that may trigger SIGSEGV in App Service sandbox.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove volatile/ref patterns, ArrayPool, and lock-based synchronization
that may cause SIGSEGV in sandboxed container environments. Use simple
List<UnsafeBufferSegment> with direct char[] allocation instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lection

UnsafeBufferSequence was not the cause. Add logging inside WriteMethod
to identify which of the 22 Widgets methods triggers the crash.
Re-enable core dump collection for lldb analysis.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…s dump state)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Force JIT compilation of IEquatable<ParameterProvider> methods before
Write path to ensure dispatch stubs are initialized.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e spread

Collection expression spread [.. methodSignature.Parameters] may not
apply implicit operator when ParameterProvider is spread into
IReadOnlyList<ValueExpression>. Use explicit Select cast.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Line 959 spreads ParameterProvider[] into IReadOnlyList<ValueExpression>
when invoking createRequestMethod. The implicit conversion is not
applied by the collection expression spread.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove diagnostic logging, SSH/lldb setup, core dump collection,
test data bundling, PrepareMethod pre-warming, and coredump endpoint.
Keep only the actual fixes (ValueExpression.cs and ScmMethodProviderCollection.cs).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp emitter:client:python Issue for the Python client emitter: @typespec/http-client-python eng meta:website TypeSpec.io updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants